package com.ikdong.toodle.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;
import com.google.gson.internal.StringMap;
import com.ikdong.toodle.exception.TDException;
import com.ikdong.toodle.model.Account;
import com.ikdong.toodle.model.BasicTask;
import com.ikdong.toodle.model.Folder;
import com.ikdong.toodle.model.Goal;
import com.ikdong.toodle.model.Task;
import com.ikdong.toodle.model.TaskContext;

public class ToodleHttpClient extends BasicHttpClient{
	public static final String appID = "toodledotask";
	public static final String appToken = "api5088e9aa4423e";
	private static final String ACCOUNT_GET_URL = "account/get.php";
	private static final String ACCOUNT_LOOKUP_URL = "account/lookup.php";
	private static final String ACCOUNT_TOKEN_URL = "account/token.php";
	private static final String FOLDER_GET_URL = "folders/get.php";
	private static final String FOLDER_ADD_URL = "folders/add.php";
	private static final String FOLDER_EDIT_URL = "folders/edit.php";
	private static final String FOLDER_DELETE_URL = "folders/delete.php";
	private static final String TASK_GET_URL = "tasks/get.php";
	private static final String TASK_ADD_URL = "tasks/add.php";
	private static final String TASK_DELETE_URL = "tasks/delete.php";
	private static final String TASK_EDIT_URL = "tasks/edit.php";
	private static final String TASK_GET_DETELTED_URL = "tasks/deleted.php";
	private static final String CONTEXT_GET_URL = "contexts/get.php";
	private static final String CONTEXT_EDIT_URL = "contexts/edit.php";
	private static final String CONTEXT_ADD_URL = "contexts/add.php";
	private static final String CONTEXT_DELETE_URL = "contexts/delete.php";
	private static final String GOAL_GET_URL = "goals/get.php";
	private static final String GOAL_EDIT_URL = "goals/edit.php";
	private static final String GOAL_ADD_URL = "goals/add.php";
	private static final String GOAL_DELETE_URL = "goals/delete.php";
	
	public static Account lookupAccount(String key){
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		String json = get(getAbsoluteUrl(ACCOUNT_GET_URL),params);
		Log.d(Constant.TAG, json);
		return JsonUtil.parseToAccount(json);
	}
	
	public static Folder addFolder(String key,Folder aFolder) throws TDException{
		Folder folder = null;
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("name", aFolder.getName());
		if(aFolder.getPrivated()!=null)
			params.put("private", aFolder.getPrivated().toString());
		String json = post(getAbsoluteUrl(FOLDER_ADD_URL),params);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONArray arr = new JSONArray(json);
				if(arr!=null && arr.length()>0){
					folder = JsonUtil.parseToFolder(arr.getJSONObject(0).toString());
				}
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.addFolder()", e);
			}
		}
		return folder;
	}
	
	public static Folder editFolder(String key,Folder aFolder) throws Exception{
		Folder folder = null;
		try {
			Map<String,String> params = new HashMap<String,String>();
			params.put("key", key);
			params.put("id", aFolder.getId().toString());
			if(aFolder.getName()!=null)
				params.put("name", aFolder.getName());
			if(aFolder.getPrivated()!=null)
				params.put("private", aFolder.getPrivated().toString());
			if(aFolder.getArchived()!=null)
				params.put("archived", aFolder.getArchived().toString());
			String json = post(getAbsoluteUrl(FOLDER_EDIT_URL),params);
			JSONArray arr = new JSONArray(json);
			if(arr!=null && arr.length()>0){
				folder = JsonUtil.parseToFolder(arr.getJSONObject(0).toString());
			}
			Log.d(Constant.TAG, "Add folder: "+json);
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.editFolder()", e);
			throw e;
		}
		return folder;
	}
	
	public static void deleteFolder(String key,Long id)throws TDException{
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("id", id.toString());		
		String json = post(getAbsoluteUrl(FOLDER_DELETE_URL),params);
		if(JsonUtil.parseError(json)!=null){
			Log.d(Constant.TAG, "Delete folder: "+json);
			throw JsonUtil.parseError(json);
		}
	}
	
	public static List<Folder> getFolders(String key){
		List<Folder> folders = new ArrayList<Folder>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		String url = getAbsoluteUrl(FOLDER_GET_URL);
		String json = get(url,params);
		Log.d(Constant.TAG, "Get folders: "+json);
		try {
			JSONArray array = new JSONArray(json);
			for(int i=0; array!=null&&i<array.length(); i++){
				JSONObject to = array.getJSONObject(i);
				Folder f = JsonUtil.parseToFolder(to.toString());
				Log.d(Constant.TAG, "Get folders - folder name: "+f.getName());
				folders.add(f);
			}
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.getFolders()", e);
		}
		return folders;
	}
	
	public static List<TaskContext> getContext(String key){
		List<TaskContext> ctxs = new ArrayList<TaskContext>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		String url = getAbsoluteUrl(CONTEXT_GET_URL);
		String json = get(url,params);
		Log.d(Constant.TAG, "Get contexts: "+json);
		try {
			JSONArray array = new JSONArray(json);
			for(int i=0; array!=null&&i<array.length(); i++){
				JSONObject to = array.getJSONObject(i);
				TaskContext ctx = JsonUtil.parseToContext(to.toString());
				Log.d(Constant.TAG, "Get contexts - context name: "+ctx.getName());
				ctxs.add(ctx);
			}
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.getContext()", e);
		}
		return ctxs;
	}
	
	public static TaskContext editContext(String key,TaskContext ctx) throws Exception{
		TaskContext uctx = null;
		try {
			Map<String,String> params = new HashMap<String,String>();
			params.put("key", key);
			params.put("id", ctx.getId().toString());
			if(ctx.getName()!=null)
				params.put("name", ctx.getName());
			if(ctx.getPrivated()!=null)
				params.put("private", ctx.getPrivated().toString());
			String json = post(getAbsoluteUrl(CONTEXT_EDIT_URL),params);
			JSONArray arr = new JSONArray(json);
			if(arr!=null && arr.length()>0){
				uctx = JsonUtil.parseToContext(arr.getJSONObject(0).toString());
			}
			Log.d(Constant.TAG, "Add context: "+json);
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.editContext()", e);
			throw e;
		}
		return uctx;
	}
	
	public static TaskContext addContext(String key,TaskContext lctx) throws TDException{
		TaskContext sctx = null;
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("name", lctx.getName());
		if(lctx.getPrivated()!=null)
			params.put("private", lctx.getPrivated().toString());
		String json = post(getAbsoluteUrl(CONTEXT_ADD_URL),params);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONArray arr = new JSONArray(json);
				if(arr!=null && arr.length()>0){
					sctx = JsonUtil.parseToContext(arr.getJSONObject(0).toString());
				}
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.addContext()", e);
			}
		}
		return sctx;
	}
	
	public static void deleteContext(String key,Long id)throws TDException{
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("id", id.toString());		
		String json = post(getAbsoluteUrl(CONTEXT_DELETE_URL),params);
		if(JsonUtil.parseError(json)!=null){
			Log.d(Constant.TAG, "Delete context: "+json);
			throw JsonUtil.parseError(json);
		}
	}
	

	
	public static List<Goal> getGoal(String key){
		List<Goal> goals = new ArrayList<Goal>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		String url = getAbsoluteUrl(GOAL_GET_URL);
		String json = get(url,params);
		Log.d(Constant.TAG, "Get goals: "+json);
		try {
			JSONArray array = new JSONArray(json);
			for(int i=0; array!=null&&i<array.length(); i++){
				JSONObject to = array.getJSONObject(i);
				Goal goal = JsonUtil.parseToGoal(to.toString());
				Log.d(Constant.TAG, "Get goals - gaol name: "+goal.getName());
				goals.add(goal);
			}
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.getGoal()", e);
		}
		return goals;
	}
	
	public static Goal editGoal(String key,Goal goal) throws Exception{
		Goal ugoal = null;
		try {
			Map<String,String> params = new HashMap<String,String>();
			params.put("key", key);
			params.put("id", goal.getId().toString());
			if(goal.getName()!=null)
				params.put("name", goal.getName());
			if(goal.getLevel()!=null)
				params.put("level", goal.getLevel().toString());
			if(goal.getArchived()!=null)
				params.put("archived", goal.getArchived().toString());
			if(goal.getContributes()!=null)
				params.put("contributes", goal.getContributes().toString());
			if(goal.getNote()!=null)
				params.put("note", goal.getNote());
			String json = post(getAbsoluteUrl(GOAL_EDIT_URL),params);
			JSONArray arr = new JSONArray(json);
			if(arr!=null && arr.length()>0){
				ugoal = JsonUtil.parseToGoal(arr.getJSONObject(0).toString());
			}
			Log.d(Constant.TAG, "Add goal: "+json);
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.editGoal()", e);
			throw e;
		}
		return ugoal;
	}
	
	public static Goal addGoal(String key,Goal lgoal) throws TDException{
		Goal sgoal = null;
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("name", lgoal.getName());
		if(lgoal.getLevel()!=null)
			params.put("level", lgoal.getLevel().toString());
		if(lgoal.getArchived()!=null)
			params.put("archived", lgoal.getArchived().toString());
		if(lgoal.getContributes()!=null)
			params.put("contributes", lgoal.getContributes().toString());
		if(lgoal.getNote()!=null)
			params.put("note", lgoal.getNote());
		String json = post(getAbsoluteUrl(GOAL_ADD_URL),params);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONArray arr = new JSONArray(json);
				if(arr!=null && arr.length()>0){
					sgoal = JsonUtil.parseToGoal(arr.getJSONObject(0).toString());
				}
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.addGoal()", e);
			}
		}
		return sgoal;
	}
	
	public static void deleteGoal(String key,Long id)throws TDException{
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("id", id.toString());		
		String json = post(getAbsoluteUrl(GOAL_DELETE_URL),params);
		if(JsonUtil.parseError(json)!=null){
			Log.d(Constant.TAG, "Delete goal: "+json);
			throw JsonUtil.parseError(json);
		}
	}
	
	public static List<Task> getTasks(Map<String,String> params){
		List<Task> Tasks = new ArrayList<Task>();
		String url = getAbsoluteUrl(TASK_GET_URL);
		String json = get(url,params);
		try {
			
			if(JsonUtil.parseError(json)==null){
				JSONArray array = new JSONArray(json);
				for(int i=1; array!=null&&i<array.length(); i++){
					JSONObject to = array.getJSONObject(i);
					Task t = JsonUtil.parseToTask(to.toString());
					Log.d(Constant.TAG, "Get tasks - task name: "+t.getTitle());
					Tasks.add(t);
				}
			}
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.getTasks()", e);
		}
		return Tasks;
	}
	
	public static List<Task> getDeletedTasks(Map<String,String> params){
		List<Task> Tasks = new ArrayList<Task>();
		String url = getAbsoluteUrl(TASK_GET_DETELTED_URL);
		String json = get(url,params);
		try {
			
			if(JsonUtil.parseError(json)==null){
				JSONArray array = new JSONArray(json);
				for(int i=1; array!=null&&i<array.length(); i++){
					JSONObject to = array.getJSONObject(i);
					Task t = JsonUtil.parseToTask(to.toString());
					Log.d(Constant.TAG, "Get deleted tasks - task name: "+t.getTitle());
					Tasks.add(t);
				}
			}
		} catch (Exception e) {
			Log.e(Constant.TAG, "ToodleHttpClient.getDeletedTasks()", e);
		}
		return Tasks;
	}
	
	public static List<Task> addTask(String key,List<BasicTask> tasks) throws TDException{
		List<Task> rtasks = new ArrayList<Task>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("tasks", JsonUtil.parseTaskToJson(tasks)); 
		String json = post(getAbsoluteUrl(TASK_ADD_URL),params);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONArray arr = new JSONArray(json);
				for(int i=0; arr!=null&&i<arr.length(); i++){
					JSONObject obj = arr.getJSONObject(i);
					Task task = JsonUtil.parseToTask(obj.toString());
					rtasks.add(task);
					
				}
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.addFolder()", e);
			}
		}
		return rtasks;
	}
	
	public static List<Task> editTask(String key,List<BasicTask> tasks) throws TDException{
		List<Task> rtasks = new ArrayList<Task>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("tasks", JsonUtil.parseTaskToJson(tasks)); 
		String json = post(getAbsoluteUrl(TASK_EDIT_URL),params);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONArray arr = new JSONArray(json);
				for(int i=0; arr!=null&&i<arr.length(); i++){
					JSONObject obj = arr.getJSONObject(i);
					Task task = JsonUtil.parseToTask(obj.toString());
					rtasks.add(task);
					
				}
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.editTask()", e);
			}
		}
		return rtasks;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<StringMap> deleteTask(String key,List<String> ids)throws TDException{
		List<StringMap> rids = new ArrayList<StringMap>();
		Map<String,String> params = new HashMap<String,String>();
		params.put("key", key);
		params.put("tasks", JsonUtil.gson.toJson(ids));		
		String json = post(getAbsoluteUrl(TASK_DELETE_URL),params);
		if(JsonUtil.parseError(json)!=null){
			Log.d(Constant.TAG, "Delete task: "+json);
			throw JsonUtil.parseError(json);
		}else{
			rids.addAll(JsonUtil.gson.fromJson(json, new ArrayList<StringMap>().getClass()));
		}
		
		return rids;
	}
	
	public static String getUserId(String email,String pass)throws TDException{
		String userid = null;
		
		String sig = MD5(email+appToken);
		String queryStr = "appid="+appID+";sig="+sig+";email="+email+";pass="+pass;
		String url = getAbsoluteUrl(ACCOUNT_LOOKUP_URL) + "?" + queryStr;
		String json = get(url,null);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONObject obj = new JSONObject(json);
				userid = obj.getString("userid");
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.getUserId()", e);
			}
		}
		
		return userid;
	}
	
	public static String getSessionToken(String userid)throws TDException{
		String token = null;
		String sig = MD5(userid+appToken);
		String queryStr = "userid="+userid+";appid="+appID+";sig="+sig;
		String url = getAbsoluteUrl(ACCOUNT_TOKEN_URL) + "?" + queryStr;
		String json = get(url,null);
		if(JsonUtil.parseError(json)!=null){
			throw JsonUtil.parseError(json);
		}else{
			try{			
				JSONObject obj = new JSONObject(json);
				token = obj.getString("token");	
			}catch(Exception e){
				Log.e(Constant.TAG, "ToodleHttpClient.getSessionToken()", e);
			}
		}

		return token;		
	}
	
	public static String getKey(String userPassword,String sessionToken){
		return MD5(MD5(userPassword)+appToken+sessionToken );
	}
	
}
